﻿#include "MainSymbolGather.h"
#include "Tools.h"
#include "SymbolDetail.h"
#include <string.h>


MainSymbolGather::SymbolNameStr::SymbolNameStr()
{
	BaseStr[0] = 0;
}

MainSymbolGather::SymbolNameStr::SymbolNameStr(const std::string &pSymbol)
{
	int plen = pSymbol.length() > Symbol_Name_Len ? Symbol_Name_Len : pSymbol.length();
	pSymbol.copy(BaseStr, plen);
	BaseStr[plen] = 0;
}

bool MainSymbolGather::SymbolNameStr::operator<(const SymbolNameStr& rhs)const 
{
	size_t leftSize = strlen(BaseStr);
	size_t rightSize = strlen(rhs.BaseStr);
	if (leftSize != rightSize)
	{
		return leftSize < rightSize;
	}
	for (int i = 0; i < leftSize; ++i)
	{
		if (BaseStr[i] != rhs.BaseStr[i])
		{
			return BaseStr[i] < rhs.BaseStr[i];
		}
	}
	return false;
}

bool MainSymbolGather::SymbolNameStr::operator==(const SymbolNameStr & rhs)
{
	size_t leftSize = strlen(BaseStr);
	if (leftSize <= 0)
	{
		return false;
	}
	size_t rightSize = strlen(rhs.BaseStr);
	if (leftSize != rightSize)
	{
		return false;
	}
	for (int i = 0; i < leftSize; ++i)
	{
		if (BaseStr[i] != rhs.BaseStr[i])
		{
			return false;
		}
	}
	return true;
}

MainSymbolGather::SymbolInfoData::SymbolInfoData()
{
	SymbolName.BaseStr[0] = 0;
	OpenInterest = 0; // 持仓量
	BeginTime = 0;
	MDRate = 0; // 活跃次数
	FinishGathing = false;
}

MainSymbolGather::MainSymbolGather()
{
	m_unSubscribeFunc = nullptr;
	init();
}

MainSymbolGather::~MainSymbolGather()
{
}

MainSymbolGather &MainSymbolGather::Instance()
{
	static MainSymbolGather pGather;
	return pGather;
}

void MainSymbolGather::init()
{
	time_t curStamp = Tools::GetCurrentTimeStamp();
	// 读取旧的主力合约（最近n个日期）
	{
		tm tmStr = Tools::GetDateTimeFrmStamp(curStamp);
		const int nDays = 10;
		for (int i = 0; i < nDays; ++i)
		{
			tm cumday = Tools::AddDays(tmStr, -i);
			SymbolPackage::MainSymbolReaderWriter mainSymbols(cumday);
			std::list<std::string> pSymbolList;
			mainSymbols.GetSymbolList(pSymbolList);
			for (std::list<std::string>::iterator it = pSymbolList.begin(); it != pSymbolList.end(); ++it)
			{
				SymbolNameStr symName(*it);
				m_oldMainSymbols.insert(symName);
			}
		}
	}
	// 读取新的主力合约
	{
		SymbolPackage::MainSymbolReaderWriter mainSymbols(Tools::GetDateTimeFrmStamp(curStamp));
		std::list<std::string> pSymbolList;
		mainSymbols.GetSymbolList(pSymbolList);
		for (std::list<std::string>::iterator it = pSymbolList.begin(); it != pSymbolList.end(); ++it)
		{
			SymbolNameStr symName(*it);
			m_newMainSymbols.insert(symName);
		}
	}
	// 读取有订单的合约
	{
		SymbolPackage::OrderSymbolReaderWriter orderSymbols;
		std::list<std::string> orderSymbolList;
		orderSymbols.GetSymbolList(orderSymbolList);
		for (std::list<std::string>::iterator it = orderSymbolList.begin(); it != orderSymbolList.end(); ++it)
		{
			SymbolNameStr symName(*it);
			m_orderSymbols.insert(symName);
		}
	}
	// 读取能源和上期的品种
	std::list<SymbolPackage::SymbolInfo> allSymbolInfoList;
	SymbolPackage::GetTheLastFutureSymbolInfoList(allSymbolInfoList);
	for (std::list<SymbolPackage::SymbolInfo>::iterator it = allSymbolInfoList.begin(); it != allSymbolInfoList.end(); ++it)
	{
		if (strcmp(it->ExchangeID, "SHFE") == 0 || strcmp(it->ExchangeID, "INE") == 0)
		{
			SymbolNameStr symbolType;
			getClassName(symbolType, it->InstrumentID);
			m_SHFEorINESymbols.insert(symbolType);
		}
	}
	// 读取所有的主力合约
	if (m_newMainSymbols.empty())
	{
		for (std::list<SymbolPackage::SymbolInfo>::iterator it = allSymbolInfoList.begin(); it != allSymbolInfoList.end(); ++it)
		{
			//std::string psymbol = it->InstrumentID;
			//std::string symboltag = psymbol.substr(0, 2);
			//if (symboltag.compare("cu") == 0)
			std::string pSymbol = it->InstrumentID;
			m_allSymbols.insert(pSymbol);
		}
	}
}


void MainSymbolGather::GetToRegSymbols(std::list<std::string> &outList)
{
	// 如果今天的主力合约已经生成，那么就只返回今天的主力合约
	if (m_newMainSymbols.empty())
	{
		for (std::set<std::string>::iterator it = m_allSymbols.begin(); it != m_allSymbols.end(); ++it)
		{
			outList.emplace_back(*it);
		}
	}
	else
	{
		for (std::set<SymbolNameStr>::iterator it = m_newMainSymbols.begin(); it != m_newMainSymbols.end(); ++it)
		{
			outList.emplace_back(it->BaseStr);
		}
	}
}

bool MainSymbolGather::IsMainSymbol(char pSymbol[81], float pOpenInterest, time_t pTime)
{
	bool isMainSymbol = checkMainSymbol(pSymbol, pOpenInterest, pTime);
	if (!isMainSymbol)
	{
		if (m_unSubscribeFunc != nullptr)
		{
			std::list<std::string> plist;
			plist.emplace_back(pSymbol);
			m_unSubscribeFunc(plist);
		}
	}
	return isMainSymbol;
}

//void MainSymbolGather::UpdateMainSymbol(const std::string &pSymbol, float pOpenInterest, time_t pTime)
//{
//	// 已经完成收集主力合约了就返回
//	if (m_finishedGather)
//	{
//		return;
//	}
//	// 当前的系统时间
//	if (m_startMarket == 0)
//	{
//		m_startMarket = pTime;
//		m_takeUnregSymbolTime = pTime;
//	}
//	// 如果是确定为非主力合约，则不判断
//	if (m_unMainSymbols.find(pSymbol) != m_unMainSymbols.end())
//	{
//		return;
//	}
//	// 如果是订单合约也不判断
//	if (m_orderSymbols.find(pSymbol) != m_orderSymbols.end())
//	{
//		return;
//	}
//	// 判断类型
//	std::string symbolClass = getClassName(pSymbol);
//	std::map<std::string, MSymbolInfo> &symbolSet = m_symbols[symbolClass];
//
//	std::map<std::string, MSymbolInfo>::iterator itSymbol = symbolSet.find(pSymbol);
//	if (itSymbol != symbolSet.end())
//	{
//		itSymbol->second.OpenInterest = pOpenInterest;
//		++itSymbol->second.Rate;
//	}
//	else
//	{
//		MSymbolInfo &pSymInfo = symbolSet[pSymbol];
//		pSymInfo.OpenInterest = pOpenInterest;
//		pSymInfo.SymbolName = pSymbol;
//	}
//
//	if (symbolSet.size() > Main_Symbol_Num)
//	{
//		std::set<MSymbolInfo, MSymbolInterestComp> tmpSets;
//		for (std::map<std::string, MSymbolInfo>::iterator tmpIt = symbolSet.begin(); tmpIt != symbolSet.end(); ++tmpIt)
//		{
//			tmpSets.insert(tmpIt->second);
//		}
//
//		std::map<std::string, MSymbolInfo> newMap;
//		int pIndex = 0;
//		for (auto it = tmpSets.rbegin(); it != tmpSets.rend(); ++it, ++pIndex)
//		{
//			if (pIndex >= Main_Symbol_Num)
//			{
//				m_unMainSymbols.insert(it->SymbolName);
//			}
//			else
//			{
//				newMap[it->SymbolName] = *it;
//			}
//		}
//		newMap.swap(symbolSet);
//	}
//}
//
//void MainSymbolGather::CheckFinishGather(time_t pTime)
//{
//	if (m_startMarket == 0)
//	{
//		return;
//	}
//	if (pTime - m_startMarket < 300)
//	{
//		return;
//	}
//	// 过滤出不活跃合约，活跃合约至少2s一次，5分钟至少150次
//	// 活跃合约
//	std::set<std::string> newMainSymbols;
//	for (std::map<std::string, std::map<std::string, MSymbolInfo>>::iterator itClass = m_symbols.begin(); itClass != m_symbols.end(); ++itClass)
//	{
//		if (itClass->second.empty())
//		{
//			continue;
//		}
//		for (std::map<std::string, MSymbolInfo>::iterator itSymbol = itClass->second.begin(); itSymbol != itClass->second.end(); ++itSymbol)
//		{
//			if (itSymbol->second.Rate > 150)
//			{
//				newMainSymbols.insert(itSymbol->first);
//			}
//			else
//			{
//				m_unMainSymbols.insert(itSymbol->first);
//			}
//		}
//	}
//
//	// m_theMainSymbols里面也有一部分很不活跃的合约，也应该取消注册
//	for (std::set<std::string>::iterator it = m_allSymbols.begin(); it != m_allSymbols.end(); ++it)
//	{
//		if (newMainSymbols.find(*it) == newMainSymbols.end())
//		{
//			m_unMainSymbols.insert(*it);
//		}
//	}
//	m_theMainSymbols.swap(newMainSymbols);
//	// 保存主力合约
//
//	SymbolPackage::MainSymbolReaderWriter mainSymbolRW(Tools::GetDateTimeFrmStamp(pTime));
//	for (std::set<std::string>::iterator it = m_theMainSymbols.begin(); it != m_theMainSymbols.end(); ++it)
//	{
//		mainSymbolRW.AppendSymbol(*it);
//	}
//	mainSymbolRW.Save();
//	m_theMainSymbols.insert(m_orderSymbols.begin(),  m_orderSymbols.end());
//	m_finishedGather = true;
//
//	m_symbols.clear();
//	m_allSymbols.clear();
//}
//
//void MainSymbolGather::TakeUnMainSymbols(std::list<std::string> &unSymbolList, time_t pTime)
//{
//	// 每隔2s取一次
//	if (pTime - m_takeUnregSymbolTime <= 2)
//	{
//		return;
//	}
//	m_takeUnregSymbolTime = pTime;
//	std::set<std::string> unRegSymbols;
//	unRegSymbols.swap(m_unMainSymbols);
//	for (std::set<std::string>::iterator it = unRegSymbols.begin(); it != unRegSymbols.end(); ++it)
//	{
//		unSymbolList.emplace_back(*it);
//	}
//}

bool MainSymbolGather::IsSHFEorINE(char pSymbol[81])
{
	if (m_SHFEorINESymbols.empty())
	{
		return false;
	}
	SymbolNameStr classType;
	getClassName(classType, pSymbol);
	if (m_SHFEorINESymbols.find(classType) == m_SHFEorINESymbols.end())
	{
		return false;
	}
	return true;
}

void MainSymbolGather::getClassName(SymbolNameStr &outClass, char pSymbol[81])
{
	for (int i = 0; i < Symbol_Name_Vec_Len; ++i)
	{
		if (isdigit(pSymbol[i]))
		{
			outClass.BaseStr[i] = 0;
			break;
		}
		outClass.BaseStr[i] = pSymbol[i];
	}
}

inline bool MainSymbolGather::checkMainSymbol(char pSymbol[81], float pOpenInterest, time_t pTime)
{
	// 名字太长了就判断为非主力合约
	int symbolNameLen = strlen(pSymbol);
	if (symbolNameLen > Symbol_Name_Len)
	{
		return false;
	}
	bool isSureMainSymbol = false;
	if (m_newMainSymbols.empty()) // 表明现在的工作是还在收集
	{
		SymbolNameStr pclassName;
		getClassName(pclassName, pSymbol);
		SymbolInfoData &symbolData = m_gatheringMainSymbols[pclassName];
		
		SymbolNameStr symbolName;
		strcpy(symbolName.BaseStr, pSymbol);
		
		// 是否是相同的合约
		if (symbolData.SymbolName == symbolName)
		{
			// 判断行情收集时间是否已经到5分钟了
			if (symbolData.FinishGathing)
			{
				isSureMainSymbol = true;
				return true;
			}
			else
			{
				if (pTime - symbolData.BeginTime > 300)
				{
					symbolData.FinishGathing = true;
					isSureMainSymbol = true;
				}
			}
			symbolData.OpenInterest = pOpenInterest;
			++symbolData.MDRate;
		}
		else
		{
			// 检查持仓量是否更多
			if (pOpenInterest > symbolData.OpenInterest)
			{
				strcpy(symbolData.SymbolName.BaseStr, pSymbol);
				symbolData.OpenInterest = pOpenInterest;
				symbolData.MDRate = 1;
				symbolData.BeginTime = pTime;
				symbolData.FinishGathing = false;
			}
		}
	}

	// 如果不确定是主力合约 那么看看他是不是老的主力合约
	if (!isSureMainSymbol)
	{
		SymbolNameStr nSymbol;
		strcpy(nSymbol.BaseStr, pSymbol);
		if (m_oldMainSymbols.find(nSymbol) != m_oldMainSymbols.end())
		{
			return true;
		}
		if (m_newMainSymbols.find(nSymbol) != m_newMainSymbols.end())
		{
			return true;
		}

	}
	return false;
}
